#include "BitFileManager.cpp"
#include "Blocksort.cpp"
int test_OBitFileManager(bool debug=true){
	cout << "[START test_OBitFileManager]" << endl;
	OBitFileManager* bitManager = new OBitFileManager("binary.dat");
	
	// La escritura del archivo se puede chequear desde consola haciendo
	// $ hexdump binary.dat
	// Pero CUIDADO que el resultado puede variar segun el procesador si
	// es little endian o big endian (http://en.wikipedia.org/wiki/Endianness)
	
	bitManager->debug = debug;
	
	/**********************************************************************/
	BlocksortCompress* bs = new BlocksortCompress();
	string L_aux;
	uInt I;
	if(debug) printf("Aplicando Blocksorting a 'PAPETAPE'...\n");
	bs->runBlock( "PAPETAPE" , &L_aux, &I );
	
	char* L = (char*)L_aux.c_str(); if(debug) printf("L: '%s'\n" , L);
	string gamma_aux = intToGamma( I ); 
	
	char* gamma = (char*)gamma_aux.c_str(); if(debug) printf("Gamma: %s\n\n" , gamma);
	delete bs;
	/**********************************************************************/
	
	
	/*
	// Test 1
	bitManager->completeToByte = false;
	bitManager->writeBinaryFileFromBinaryRepresentationString( gamma );
	
	
	bitManager->completeToByte = false;
	bitManager->completeToByteLastChar = true;
	bitManager->clearBuffer = false;
	bitManager->writeBinaryFileFromTextString( L );
	*/
	
	
	// Test 2
	//cout << (char*)(intToGamma(8)).c_str() << endl;
	bitManager->writeBinaryString( (char*)(intToGamma(8)).c_str() );
	bitManager->writeBinaryString( gamma );
	bitManager->writeText( L );
	
	
	/*
	// Test 3
	bitManager->writeBinaryString( "1" );
	bitManager->writeBinaryString( &gamma_aux );
	bitManager->writeText( &L_aux );
	bitManager->writeBinaryString( "10 1111 111" );
	*/
	
	/*
	// Test 4
	char* cadenaBinaria = (char*)"1010 1110 1111 100";
	bitManager->completeToByte = false;
	bitManager->writeBinaryFileFromBinaryRepresentationString( cadenaBinaria );
	*/
	
	delete bitManager;
	cout << "[END test_OBitFileManager]" << endl << endl;
	return 0;
}

int test_IBitFileManager_getNextBit(bool debug=true){
	cout << "[START test_IBitFileManager_getNextBit]" << endl;
	IBitFileManager bitManager("binary.dat");
	bitManager.debug = debug;
	uChar bit;
	uInt i = 1;
	while(true){
		if( ERROR_EOF == bitManager.getNextBit(&bit) ) break;
		printf( "%c" , bit );
		//if( i == 8*4 ) break;
		if( i % 8 == 0 ) printf(" ");
		i++;
	}
	printf( "\n" );
	
	cout << "[END test_IBitFileManager_getNextBit]" << endl << endl;
	return 0;
}

int test_IBitFileManager_getNextBits(bool debug=true){
	cout << "[START test_IBitFileManager_getNextBits]" << endl;
	
	IBitFileManager bitManager("binary.dat");
	uInt amountBits = 5;
	bitManager.debug = debug;
	string* texto = new string;
	
	bool is_eof = false;
	
	while(true){
		is_eof = ( ERROR_EOF == bitManager.getNextBits(amountBits,texto) );
		cout << *texto << endl;
		if(is_eof) break;
	}
	
	printf( "\n" );
	
	delete texto;
	cout << "[END test_IBitFileManager_getNextBits]" << endl << endl;
	return 0;
}

int test_IBitFileManager_getNextByte(bool debug=true){
	
	cout << "[START test_IBitFileManager_getNextByte]" << endl;
	
	IBitFileManager* bitManager = new IBitFileManager("binary.dat");
	bitManager->debug = debug;
	uChar byte;
	char cont = 0;
	while(true){
		if( ERROR_EOF == bitManager->getNextByte(&byte) ) break;
		cont++; printf( "%02X" , byte ); if(cont==2){ printf(" "); cont = 0; }
	}
	printf( "\n" );
	
	delete bitManager;
	cout << "[END test_IBitFileManager_getNextByte]" << endl << endl;
	return 0;
}

int test_IBitFileManager_getNextBytes(bool debug=true){
	cout << "[START test_IBitFileManager_getNextBytes]" << endl;
	
	IBitFileManager bitManager("binary.dat");
	uInt bytes = 8;
	bitManager.debug = debug;
	string* texto = new string;
	
	bool is_eof = false;
	
	while(true){
		is_eof = ( ERROR_EOF == bitManager.getNextBytes(bytes,texto) );
		cout << *texto << endl;
		if(is_eof) break;
	}
	
	printf( "\n" );
	
	delete texto;
	cout << "[END test_IBitFileManager_getNextBytes]" << endl << endl;
	return 0;
}

int main(int argc , char* argv[]) {
	bool debug = false;
	
	if( argc == 2 ){
		debug = true;
	}
	
	test_OBitFileManager(debug);
	
	test_IBitFileManager_getNextBit(debug);
	test_IBitFileManager_getNextBits(debug);
	test_IBitFileManager_getNextByte(debug);
	test_IBitFileManager_getNextBytes(debug);
	
	return 0;
}
